import { uuid } from "@pureadmin/utils";
import { useUserStoreHook } from "@/store/modules/user";
import { getToken } from "@/utils/auth";

class WebSocketClient {
  constructor(url, options = {}) {
    this.url = url; // WebSocket 服务器地址
    this.reconnectInterval = options.reconnectInterval || 5000; // 断线重连间隔时间，默认 5 秒
    this.heartbeatInterval = options.heartbeatInterval || 10000; // 心跳间隔时间，默认 10 秒
    this.maxRetries = options.maxRetries || Infinity; // 最大重连次数，默认无限
    this.retries = 0; // 当前重连次数

    this.ws = null;
    this.heartbeatTimer = null;
    this.reconnectTimer = null;
    this.isManuallyClosed = false;

    this.actionHandler = {}; // 消息处理器

    // callback promise
    this.callbackMap = new Map();

    // 心跳消息action
    this.heartbeatAction = "mdc.heartbeat";

    // 响应消息action
    this.respAction = "resp.msg";

    this.connect(); // 初始化连接
  }

  // 注册消息处理器
  registerActionHandler(action, handler) {
    this.actionHandler[action] = handler;
  }

  // 取消注册消息处理器
  unregisterActionHandler(action) {
    delete this.actionHandler[action];
  }

  // 建立 WebSocket 连接
  connect() {
    if (this.retries >= this.maxRetries) {
      console.error(`Max retries reached. Cannot reconnect to ${this.url}`);
      return;
    }

    this.ws = new WebSocket(this.url);

    this.ws.onopen = () => {
      console.log(`Connected to ${this.url}`);
      this.retries = 0;
      this.startHeartbeat(); // 开始心跳
    };

    this.ws.onmessage = event => {
      const eventMsg = JSON.parse(event.data);
      const { action } = eventMsg;
      if (action === this.respAction) {
        // 响应消息处理
        const { seq } = eventMsg;
        const { resolve } = this.callbackMap.get(seq) || {};
        if (resolve) {
          resolve(eventMsg);
        }
        this.callbackMap.delete(seq);
        return;
      }
      console.log("Received message:", event.data);
      if (this.actionHandler[action]) {
        this.actionHandler[action](eventMsg);
      }
    };

    this.ws.onclose = event => {
      console.log("WebSocket closed:", event);
      if (!this.isManuallyClosed) {
        this.reconnect();
      }
    };

    this.ws.onerror = error => {
      console.error("WebSocket error:", error);
      this.ws.close(); // 触发 `onclose` 事件
    };
  }

  // 发送消息
  sendMessage(message) {
    let { seq } = message;
    if (!seq) {
      // 使用 uuid 生成唯一序列号
      seq = uuid();
      message.seq = seq;
    }
    if (this.ws && this.ws.readyState === WebSocket.OPEN) {
      this.ws.send(JSON.stringify(message));
    } else {
      console.error("WebSocket is not open. Cannot send message.");
    }
    return new Promise((resolve, reject) => {
      this.callbackMap.set(seq, { resolve, reject });
    });
  }

  // 启动心跳
  startHeartbeat() {
    this.stopHeartbeat(); // 避免重复启动
    this.heartbeatTimer = setInterval(() => {
      if (this.ws && this.ws.readyState === WebSocket.OPEN) {
        const heartBeatMsg = {
          action: this.heartbeatAction,
          seq: uuid()
        };
        this.ws.send(JSON.stringify(heartBeatMsg));
        console.log("Sent heartbeat:", heartBeatMsg.seq);
      }
    }, this.heartbeatInterval);
  }

  // 停止心跳
  stopHeartbeat() {
    if (this.heartbeatTimer) {
      clearInterval(this.heartbeatTimer);
      this.heartbeatTimer = null;
    }
  }

  // 断线重连
  reconnect() {
    if (this.reconnectTimer) return; // 避免多次启动重连

    this.retries += 1;
    console.log(
      `Reconnecting in ${this.reconnectInterval / 1000} seconds... (Attempt ${this.retries})`
    );

    this.reconnectTimer = setTimeout(() => {
      this.connect();
      this.reconnectTimer = null; // 重置重连计时器
    }, this.reconnectInterval);
  }

  // 关闭连接
  close() {
    this.stopHeartbeat();
    if (this.ws) {
      this.ws.close();
    }
    if (this.reconnectTimer) {
      clearTimeout(this.reconnectTimer);
    }
  }

  // 手动关闭连接
  manualClose() {
    this.isManuallyClosed = true;
    this.close();
  }

  // 重新连接并重置状态
  reset() {
    this.isManuallyClosed = false;
    this.retries = 0;
    this.close();
    this.connect();
  }
}

const { accessToken, refreshToken } = getToken();

const wsClient = new WebSocketClient(
  // `ws://127.0.0.1:8899?x-member-id=${useUserStoreHook().username}`
  `ws://43.200.171.158:9080/chat-ws/?x-member-id=${useUserStoreHook().username}&fated_access_token=${accessToken}&fated_refresh_token=${refreshToken}`
  // `ws://101.132.44.88:8899?X-Member-Id=${useUserStoreHook().username}`
);

export default wsClient;
